package org.redis.cluster.transport.client.pool;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.redis.cluster.RedisCluster;
import org.redis.cluster.config.ClientConfig;
import org.redis.cluster.extension.ExtensionLoader;
import org.redis.cluster.plugin.Plugin;
import org.redis.cluster.transport.client.Client;
import org.redis.cluster.transport.client.ClientFactory;
import org.redis.cluster.transport.client.IPooledClientFactory;
import org.redis.cluster.transport.protocol.ProtocolDecoder;
import org.redis.cluster.transport.protocol.ProtocolEncoder;

public class PooledClientFactory extends BasePooledObjectFactory<Client> implements IPooledClientFactory,Plugin {

	private ExtensionLoader extensionLoader;
	private ClientConfig config;
	private ProtocolDecoder decoder;
	private ProtocolEncoder encoder;
	private ClientFactory clientFactory;
	
	public PooledClientFactory(ClientConfig config,ProtocolDecoder decoder,ProtocolEncoder encoder) {
		this.config=config;
		this.decoder=decoder;
		this.encoder=encoder;
	}
	
	@Override
	public void init(RedisCluster redisCluster) {
		this.extensionLoader=redisCluster.getExtensionLoader();
		this.clientFactory=initClientFactory();
	}
	
	@Override
	public void destroy() {
	}
	
	protected ClientFactory initClientFactory() {
		return extensionLoader.load(config.getClient(), ClientFactory.class, config,decoder,encoder);
	}
	
	@Override
	public Client create() throws Exception {
		return clientFactory.getClient();
	}

	@Override
	public void destroyObject(PooledObject<Client> wrap) throws Exception {
		Client client=wrap.getObject();
		client.close();
	}
	
	@Override
	public PooledObject<Client> wrap(Client client) {
		return new DefaultPooledObject<Client>(client);
	}
	
}